به نام خدا

پروژه‌ی یادگیری ماشین

علیرضا توکلی ۸۱۰۱۹۷۶۸۶

هدف از انجام

هدف از انجام این پروژه بررسی الگوریتم‌های یادگیری ماشین و پیش‌پردازش داده‌ها می‌باشد.

توضیح کلی پروژه

در این پروژه ما با داده‌هایی از فروش خانه‌هایی مواجهیم که می‌بایست با توجه به ویژگی‌های داده شده، خانه‌های دیگری را قیمت گزاری کنیم. ابتدا باید داده‌ها را به خوبی بشناسیم. برای این مرحله از نمودارهای مختلف استفاده می‌کنیم. پس از آن داده‌ها را پیش‌پردازش کنیم؛ یعنی داده‌های ناقص را درست کنیم و در آخر نیز الگوریتم‌های یادگیری را اعمال می‌کنیم.

داده‌های مورد استفاده

داده‌های مورد استفاده در این پروژه از سایت kaggle آمده‌اند که هدف از آن‌ها یادگیری است.

Phase 0

1

با بررسی دو سلول بالا می‌توان شهود کلی‌ای از دیتای مورد نظر پیدا کرد. تعداد ستون‌ها و سطرها، نوع هر ستون، مقدار حافظه و تعداد مقادیر غیر خالی هر ستون مشخص شده است.

شهود کلی‌ای از دیتای مورد نظر به ما می‌دهد. مثلا برای id ما انتظار داشتیم که از ۱ تا ۱۴۶۰ باشد که یعنی تمامی سطرها آیدی مربوط به خودشان را داشته باشند. یا مثلا از MSSubClass انتظار داشتیم طبق data_description مقادیر گسسته‌ی گفته شده را بگیرد که می‌بینیم مینیمم 20 است و نیمی از داده‌ها ۵۰ یا کم‌تر از آن هستند.

2

3

چهار ویژگی گفته شده در بالا، بیش‌ترین کورلیشن را با مقدار هدف ما داشتند و به ترتیب نمایان‌گر کیفیت منابع استفاده شده در ساختن خانه، مساحت طبقات بالایی، تعداد ماشین‌هایی که می‌توان در گاراژ گذاشت و مساحت گاراژ مورد نظر هستند. این نشان می‌دهد که بر خلاف شرایط فعلی ما در ایران، شاید مساحت خونه برای آن‌ها خیلی تاثیر جدی‌ای ندارد و تاثیر تعداد ماشین‌ها در گاراژ مهم‌تر است.

4

بله. همان‌طور که می‌بینید، مقدار کورلیشن‌ها و بعضا ترتیب فیچرها تغییر کرده است. دلیل این نیز واضح است. زیرا کورلیشنی که ما حساب می‌کنیم، شهودی از خطی بودن دو ویژگی به ما می‌دهد. اما همان‌طور که در تصاویر بعدی مشاهده می‌کنید، ممکن است ویژگی‌ها با هم رابطه‌ای غیر خطی داشته باشند. مثلا به توان برسند. اگر به توان برسند و ما از log استفاده کنیم، کورلیشن این ویژگی‌ها زیاد می‌شود.

5

خیر؛ زیرا ما از داده‌های عددی تنها استفاده کردیم. پس باید برای داده‌های غیر عددی‌مان کاری انجام دهیم. ایراد بعدی‌ای که می‌توان گفت، می‌تواند این باشد که ما ویژگی‌هایی که ممکن است رابطه‌ی قابل قبولی با ویژگی هدف داشته باشند را به دلیل خطی نبودن کنار گذاشتیم. مثلا فرض کنید قیمت خانه با متراژ خانه رابطه‌ی توان دویی دارد؛ یعنی اگر مساحت $x$ باشد، قیمت خانه $x^2$ خواهد بود. در صورتی که کورلیشن به ما عدد کمی نشان خواهد داد.

6

همان‌طور که می‌بینید ویژگی OverallQual رابطه‌ی غیرخطی خود را با قیمت خانه نشان می‌دهد. به همین خاطر بود که با $log$ گرفتن از قیمت خانه، به کورلیشن بالاتری دست پیدا کرده بودیم. برای متراژ طبقه‌های بالایی و گاراژ نیز کمی این خطی زیاد شدن قیمت مشخص است. چیزی که جالب است، وجود بعضی داده‌های پرت در این دو نمودار است. مثلا خانه‌ای وجود دارد که با متراژ بسیار بالا، قیمت کمی دارد. در مورد تعداد ماشین‌هایی که در گاراژ جا می‌شوند نیز می‌توان کمی غیرخطی بودن این دو ویژگی نسبت به هم را دید. اما نکته‌ی مهم پراکندگی قیمت به ازای هر تعداد ماشین می‌باشد که کار را سخت می‌کند و نکته‌ی مهم‌تر نیز وجود درصد بالایی از خانه‌های ۲ ماشینه، نسبت به کل داده‌هاست که می‌تواند در یادگیری مشکل‌ساز شود.

7

ما با توجه به این که در ایران زندگی می‌کنیم، احتمالا با توجه به تفاوت‌های فرهنگی‌ای که داریم نتوانیم خیلی دقیق و خوب این ویژگی‌ها را انتخاب کنیم؛ اما از نظر من، در بین ویژگی‌های دسته‌ای، فکر می‌کنم سه ویژگی MSZoning ،Neighborhood و SaleCondition ویژگی‌های دسته‌ای تاثیرگذارمان باشند.

8

Phase 1

1

روش دیگر می‌تواند حذف سطر مورد نظر باشد. چندین روش دیگر نیز در پروژه‌های قبلی گفته شد. مثل این که داده‌ی سطر قبلی یا بعدی را به سطر بعدی که ستونش داده‌ای ندارد، منتقل کنیم. به نظرم بسته به شرایط می‌توانیم کار‌های مختلفی کنیم. مثلا فرض کنید برای خانه‌های تهران داده جمع کرده‌ایم و در ویژگی‌ استخر داشتن یا نداشتن آن، برای خانه‌هایی که استخر داشته‌اند YES داریم و در غیر این صورت داده‌ها را یادمان رفته وارد کنیم و NaN هستند. در این صورت اگر ما از مقداری استفاده کنیم که بیش‌ترین تکرار را دارد،ِ آن‌گاه همه‌ی داده‌هایمان YES می‌شوند. در صورتی که می‌دانیم که خانه‌های تهران عموما استخر ندارند. (حداقل ما که ندیدیم :)) اما مثلا به عنوان مثال برای متراژ خانه اگر از میانگین استفاده کنیم، به نظرم می‌تواند معقول باشد. ممکن است از ویژگی‌ای شناختی نداشته باشیم و تعداد NaNهای این ویژگی زیاد باشد. در این صورت بسته به شرایط، ممکن است بهترین راه این باشد که این ستون حذف شود.

حذف کردن سطر در زمانی که تعداد داده‌هایمان زیاد است می‌تواند به خوبی عمل کند. جایگزین کردن با آماره‌ها، باید با آگاهی از ویژگی صورت بگیرد. حذف ویژگی نیز می‌تواند خوب باشید اگر تعداد ویژگی‌های مفیدمان زیاد باشد و داده‌های کمی از این ویژگی داشته باشیم.

2

ویژگی‌ها با توجه به میزان داده‌های گم‌شده مرتب کرده‌ایم. لزوما نباید ویژگی‌هایی که درصد بالایی کاستی دارند را حذف کنیم. هر ویژگی را به صورت جدا مورد بررسی قرار می‌دهیم.

PoolQC, MiscFeature, Fence, FireplaceQu, GarageCond, GarageType, GarageFinish, GarageQual, BsmtExposure, BsmtFinType1, BsmtFinType2, BsmtCond, BsmtQual, MasVnrType

از آن‌جایی که در دیتای این ویژگی تنها کیفیت‌ها را داریم. پس احتمال این که بقیه‌ی داده‌هایی که این ویژگی برای آن‌ها مقدار ندارد، مثلا استخر نداشته باشند بسیار زیاد است. در ضمن خانه‌های استخر دار کم هستند. پس راه منطقی برای این خانه‌ها این است که مقادیر آن‌ها را با NA پر کنیم.

Alley

به دلیل کم اهمیت بودن این ویژگی از نظر ما، درصد بالای نبود اطلاعات و عدم پیش‌بینی پذیری آن برای داده‌هایی که این اطلاعات را ندارند، این ویژگی از داده‌ی ما حذف می‌شود.

LotFrontage, GarageYrBlt, MasVnrArea

سه ویژگی بالا عددی بوده و می‌توانند میانگین بقیه دیتا را بگیرند. از میانگین برای آن‌ها استفاده می‌کنیم.

Electrical

از آن جایی که نمی‌توانیم تصمیم قطعی‌ای برای این ویژگی بگیریم و تاثیر آن در قیمت طبق فاز ۰ کم است، می‌توانیم این ویژگی را حذف کنیم.

3

برای این که تاثیر واحد هر ویژگی در پیش‌بینی ما تاثیری نگذارد، ما از روش‌های گفته شده استفاده می‌کنیم. مثلا زمانی که مبلغ خانه به ریال باشد و متراژ خانه به کیلومتر مربع باشد، باید ضریب مربوط به متراژ بسیار زیاد باشد و طبق الگوریتم‌هایی که ما داریم و مانند گرادیان دیسنت قدم‌های بزرگی می‌طلبد. پس بهتر است داده‌ها را نرمالایز کنیم.

4

یک روش one-hot موجود است که به ازای هر مقدار یک ستون می‌گذارد و اگر برای هر داده، این مقدار درست باشد، در ستون ۱ و در غیر این صورت ۰ می‌نویسد. روش دیگری که موجود است، دادن مقادیر ۱ ۲ ۳ ۴ ۵ الی آخر به کلاس‌ها است. در بعضی از ویژگی‌ها که ترتیب آن‌ها مانند ۱ ۲ ۳ ۴ و ... است، این کار مفید است؛ اما در شرایطی که کلاس‌ها به هم ربطی نداشته باشند، این که مثلا کلاس پیکان را ۱ بگذاریم، بی‌ام‌وه را ۲ و بنز را ۳ بگذاریم، یک فرض غلط به الگوریتم‌های آموزش ما می‌دهد که فاصله‌ی پیکان تا بی‌ام‌وه و بنز تا بی‌ام‌وه یکی است. (که هست :)) در دیتای ما نیز مواردی وجود دارد که می‌توان آن‌ها را ترتیبی نوشت.

5

ابتدا برای راحتی بیش‌تر ویژگی‌هایی که حس می‌کنیم کم‌تر به درد می‌خورند را طبق هیت مپی که کشیده شد، حذف می‌کنیم که مراحل تبدیل داده‌های categorical راحت‌تر باشد. واضح است که نباید همه ستون‌ها را نگه داریم. نگه داشتن تعداد زیادی ویژگی باعث می‌شود، الگوریتم‌هایی مانند KNN بد کار کنند زیرا فاصله‌ی داده‌ها از هم زیاد می‌شوند.

6

در کورس‌های مختلف دیده‌ام که درصد جداسازی P اگر حدود ۲۰ درصد باشد بسیار عالی است و این را به تجربه می‌گفتند. البته بستگی به تعداد دیتاهای موجود نیز دارد.

بله روش‌های دیگری نیز وجود دارد. مثلا می‌توان یک تکه‌ی کوچکی از داده‌ها را آموزش داد بعد باقی داده‌ها را آزمایش کرد، سپس از داده‌های آزمون دوباره مقداری را آموزش داد و دوباره این فرآیند را تکرار کرد.

بله. خیلی مهم است که داده‌ها به صورت تصادفی تقسیم شوند. زیرا ممکن است که داده‌ها با یک منطقی نوشته شده باشند. مثلا زمان فروششان. پس یک ترتیبی داشته باشند و این برای آموزش ما بد است. البته در شرایطی هم وجود دارد (مثل مسابقه‌ی دیتادیز پارسال شریف) که ما مجبوریم دسته‌ای از داده‌ها را با هم پیش‌بینی کنیم. در این صورت باید دسته‌ها را مشخص کرده و بین آن‌ها رندوم انتخاب کنیم.

Phase 2

KNN

Decision Tree

LinearRegression

3

overfitting زمانی رخ می‌دهد که مدل ما بسیار پیچیده شده باشد و روی داده‌های آزمایشی به خوبی عمل کند اما در داده‌های جدید آزمایشی، درست کار نکند. (به دلیل پیچیدگی زیاد.) underfitting نیز زمانی است که مدل ما بسیار ساده باشد و در این صورت نه روی داده‌های آزمایشی خیلی خوب کار می‌کند و نه روی داده‌های آزمون. مثلا در مثال‌های بالا اگر نمودارهای کشیده شده را مشاهده کنید، می‌بینید که از یک جایی به قبل یا بعد، ارورهای آزمایشی نزدیک به صفر شده‌اند. این یعنی ممکن است گرفتار overfitting شده باشیم. حالتی خوب است که ارورهای آزمایشی باشد و ارور آزمون در کم‌ترین حالت خود باشد. که مقادیر به دست آمده در روش‌ها از این خاصیت پیروی می‌کنند. پس احتمالا نه overfitting داریم و نه underfitting.

4

ویژگی‌های مختلفی اضافه و کم شد و تغییرات هر کدام بررسی شد. در انتها به این سری ویژگی‌ها رسیدیم که بازخورد خوبی به ما در داده‌هایمان داد. با حذف ویژگی‌های کم اهمیت تغییر زیادی را در نتیجه‌ی الگوریتم می‌دیدیم. با این که این الگوریتم‌ها، مثلا linear regression، می‌توانند ضریب تاثیر هر ویژگی را خودشان انتخاب کنند و نقش یک ویژگی را کم کنند، با این حال، اگر ما از ویژگی‌های اضافی پرهیز کنیم، به شرایطی بهتر می‌رسیم.

Phase 3

1

2

3

این روش از دو تا از روش‌های قبلی بهتر و از یکی از آن‌ها بدتر است. دلیل برتری این روش می‌تواند وجود روش linear regression در آن باشد. بالاخره داریم روشی که جواب خوبی می‌داد را با روش‌هایی که جواب‌های خوبی نمی‌دادند ترکیب می‌کنیم. پس انتظار بد بودن جواب منطقی است. اگر ارورها نزدیک به هم بود، شاید می‌توانستیم انتظار داشته باشیم که ترکیب این روش‌ها روشی بهتر به ما خروجی بدهد.

نتیجه‌گیری کلی

در بین روش‌های استفاده شده، الگوریتم linear regression بهترین نتیجه را داشت و متوجه شدیم که حذف ویژگی‌های اضافی چه قدر می‌تواند باعث بهبود الگوریتم ما بشود.

منابع استفاده شده

از منابع زیادی در کشیدن نمودارها تا استفاده از هر کدام از توابع استفاده شد؛ اما بعضی از این منابع را در کنار کد‌ها گذاشته‌ام.